package com.example.es.api;

import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.net.HostAndPort;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Created by yanlei on 2017/7/9.
 */
public class ESClient {
    ESConfig esConfig = new ESConfig();

    public ESConfig getEsConfig() {
        return esConfig;
    }

    public void setEsConfig(ESConfig esConfig) {
        this.esConfig = esConfig;
    }

    TransportClient client  = null;
    volatile  boolean initFlag = false;
    private TransportClient getClient(){
        if(!initFlag){
            synchronized (this){
                if(!initFlag){
                    final  ESConfig esConfigLocal = this.esConfig;
                    Preconditions.checkNotNull(esConfigLocal,"ESClient.esConfig is null");
                    esConfigLocal.validate();
                    Settings settings = Settings.builder()
                            .put("cluster.name", esConfigLocal.getClusterName())
                            .put("client.transport.sniff", true)
                            .build();
                    final TransportClient client = new PreBuiltTransportClient(settings);
                    Iterators.all(esConfigLocal.getHostAndPortList().iterator(), new Predicate<HostAndPort>() {
                        @Override
                        public boolean apply(HostAndPort input) {
                            try {
                                client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(input.getHostText()), input.getPort()));
                                return true;
                            } catch (UnknownHostException e) {
                                throw new RuntimeException("UnknownHostException:" + esConfigLocal.getIpAndPorts(), e);
                            }
                        }
                    });
                    this.client = client;
                    initFlag = true;
                }
            }
        }
        return client;
    }
    EsAdmin esAdmin = null;

    public EsAdmin getEsAdmin() {
        if ( esAdmin == null) {
            AdminClient adminClient = this.getClient().admin();
            EsAdmin esAdmin  = new EsAdmin(adminClient);
            this.esAdmin = esAdmin;
        }
        return esAdmin;
    }

    public IndexResponse createIndex(String index, String type, String json){
        IndexResponse response = getClient().prepareIndex(index, type)
                .setSource(json, XContentType.JSON)
                .get();
        return response;
    }
    public IndexResponse index(IndexRequest indexRequest){
       return   this.getClient().index(indexRequest).actionGet();
    }
    public GetResponse get(GetRequest getRequest){
        return this.getClient().get(getRequest).actionGet();
    }
    public  void close(){
         if(initFlag){
             this.client.close();
         }
    }
}
